<template>
    <div id="gomoku">
        <h2>决战-五子棋</h2>
        <div class="inps">
            <input v-model="room" placeholder="房间名" style="margin-right: 10px;">
            <input v-model="playerName" placeholder="请输入您的大名" style="margin-right: 10px;">
            <button @click="joinRoom">加入房间</button>
        </div>
        <div v-if="(!board||board.length==0)&&!oneTip">
            <h3>温馨提示：创房者先手，加入者后手。</h3>
        </div>
        <div class="middel">
            <div class="m_player" v-if="playerNames.length">
                <h3>玩家1：({{ playerId==players[0]?'自己':'对方' }})</h3>
                <h2>{{ playerNames[0] }}</h2>
            </div>
            <div id="board" :style="boardStyle" v-if="board&&board.length>0">
                <div v-for="(row, x) in board" :key="x" class="row">
                    <div v-for="(cell, y) in row" :key="y"
                        :class="['cell', 
                        cell ? (cell.id === playerId ? 'black' : 'white') : '', lzNum===(cell&&cell.step)?'last':'']" @click="makeMove(x, y)">
                    </div>
                </div>
            </div>
            <div class="m_player" v-if="playerNames.length">
                <h3>玩家2：({{ playerId==players[1]?'自己':'对方' }})</h3>
                <h2>{{ playerNames[1] }}</h2>
            </div>
        </div>
        <div v-if="board&&board.length>0&&!winner" style="margin-top: 20px;">
            <h3>当前应落子者：玩家{{ currentId==players[0]?1:2 }}({{ currentId==players[0]?playerNames[0]:playerNames[1] }})</h3>
        </div>
        <div v-if="oneTip">
            <h3>您已创建房间[{{ room }}]，请等待对方加入房间开始决战</h3>
        </div>
        <div v-if="gameTip&&(!board||board.length==0)" style="margin-top: 50px;">
            <h3 style="color: red;">房间[{{ room }}]已满两人，请重新开房</h3>
        </div>
        <div v-if="winner" class="winner" style="margin-top: 50px;">
            <h3>{{ winner }}</h3>
            <button @click="restartGame">重新开始游戏</button>
        </div>
    </div>
</template>
    
<script>
import io from 'socket.io-client';
export default {
    data() {
        return {
            socket: null,
            board: null,
            room: '',
            playerId: null,
            winner: null,
            players: [], // 玩家id
            playerName: '', // 玩家名字
            playerNames: [], // 存储当前房间的玩家名
            gameTip:false,
            oneTip:false,
            currentId:'',
            lzNum:''         
        };
    },
    computed: {
        boardStyle() {
            return {
                display: 'grid',
                gridTemplateColumns: `repeat(15, 40px)`
            };
        },
    },
    methods: {
        joinRoom() {
            this.socket = io('http://106.54.209.120:3000');
            this.socket.on('connect', () => {
                this.playerId = this.socket.id; // 获取id
            });
            // 发送房间名和玩家名字
            this.socket.emit('joinRoom', { room: this.room, playerName: this.playerName });

            this.socket.on('startGame', ({ board, playerNames ,players }) => {
                this.board = board;
                this.playerNames = playerNames;
                this.players = players;
                this.gameTip = false;
                this.oneTip = false;
                this.currentId = this.players[0];
            });

            this.socket.on('updateBoard', ({board,currentId}) => {
                this.board = board;
                this.currentId = currentId;
                let sumArr = this.board.reduce((pre, cur) => pre.concat(cur));
                this.lzNum = sumArr.filter(item => item&&item.id).length;   
            });

            this.socket.on('resetBoard', (board) => {
                this.board = board;
                this.winner = null;
            });

            this.socket.on('gameOver', (playerId) => {
                this.winner = playerId === this.socket.id ? '最终战况：你赢了！' : '最终战况：你输了！';
            });
            
            this.socket.on('oneTip', (room) => {
                this.oneTip = true;
                this.room = room;
            }); 
            this.socket.on('gameTip', (room) => {
                this.gameTip = true;
                this.room = room;
            });
        },
        makeMove(x, y) {
            if (!this.board[x][y] && this.playerId) {
                let sumArr = this.board.reduce((pre, cur) => pre.concat(cur));
                let count1 = sumArr.filter(item => item&&item.id === this.players[0]).length;   
                let count2 = sumArr.filter(item => item&&item.id === this.players[1]).length;

                if(count1==0&&count2==0&&this.players[1]==this.playerId){
                    return alert('您为后手，请等待对方落子');
                }

                if((count1==0&&count2==0)
                    ||(count1==count2&&this.players[0]==this.playerId)
                    ||(count1>count2&&this.players[1]==this.playerId)
                    ||(count1<count2&&this.players[0]==this.playerId)
                ){
                    let currentId = this.currentId==this.players[0]?this.players[1]:this.players[0];
                    this.socket.emit('makeMove', { room: this.room, x, y, currentId });
                }else alert('请等待对方落子');
            }
        },
        restartGame() {
            this.socket.emit('restartGame', this.room);
        },
    }
};
</script>
    
<style>
.winner {
    color: red;
    font-weight: bold;
}
#gomoku{
    display: flex;
    flex-direction: column;
    align-items: center;
}

.inps{
    display: flex;
    align-items: center;
    margin-bottom: 20px;
}

.middel{
    display: flex;
    align-items: center;
}

#board{
    background: url(../assets/bg.jpg) no-repeat;
    background-size: cover;
    box-shadow: 4px 4px 6px 4px #888;
    margin: 0 100px;
}

.cell {
    width: 40px;
    height: 40px;
    border: 1px solid #666;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    position: relative;
}
.cell::after {
    content: '';
    width: 100%;
    height: 100%;
    border-radius: 50%;
}

.cell.black::after {
    border: 1px solid #999;
    background: linear-gradient(to right bottom,#000 10%,#fff 5%,#000 85%);
}

.cell.white::after {
    border: 1px solid lightgray;
    background: linear-gradient(to right bottom,grey 5%,#fff 15%,#999 100%);
}
.cell.last::after {
    box-shadow: 4px 4px 6px 2px #666;
    z-index: 1;
}
</style>